package gov.pbc.nn.kjgl.software.view;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import gov.pbc.nn.core.bdf.entity.Dept;
import gov.pbc.nn.core.utils.SecurityUtils;
import gov.pbc.nn.kjgl.entity.Project;
import gov.pbc.nn.kjgl.entity.ProjectFile;
import gov.pbc.nn.kjgl.software.dao.ProjectDao;
import gov.pbc.nn.kjgl.software.dao.ProjectJdbcDao;
import gov.pbc.nn.uflo.entity.Opinion;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.DataResolver;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.core.Configure;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
import com.bstek.dorado.data.variant.Record;
import com.bstek.dorado.uploader.DownloadFile;
import com.bstek.dorado.uploader.UploadFile;
import com.bstek.dorado.uploader.annotation.FileProvider;
import com.bstek.dorado.uploader.annotation.FileResolver;
import com.bstek.uflo.client.service.ProcessClient;
import com.bstek.uflo.client.service.TaskClient;
import com.bstek.uflo.model.ProcessInstance;
import com.bstek.uflo.model.task.Task;
import com.bstek.uflo.service.StartProcessInfo;
import com.bstek.uflo.service.TaskOpinion;

@Component("projectPR")
public class ProjectPR {

	@Autowired
	private ProjectDao projectDao;

	@Autowired
	private ProjectJdbcDao projectJdbcDao;

	@Autowired
	@Qualifier(TaskClient.BEAN_ID)
	private TaskClient taskClient;

	@Autowired
	@Qualifier(ProcessClient.BEAN_ID)
	private ProcessClient processClient;

	@Transactional
	@DataResolver
	public void saveProject(List<Project> project) {
		projectDao.saveProject(project);
	}

	@Transactional
	@DataResolver
	public void saveProjectToo(List<Project> project) {
		projectDao.saveProjectToo(project);
	}

	@Transactional
	@DataResolver
	public void saveOneProject(Project project) {
		projectDao.update(project);
	}

	@Transactional
	@Expose
	public void deleteProject(List<String> list) {
		projectDao.deleteProject(list);
	}

	@Transactional
	@Expose
	public void deleteFile(String id) {
		projectDao.deleteFile(id);
	}

	@DataProvider
	public void loadProject(Page<Project> page, Criteria criteria) {
		this.projectJdbcDao.loadProject(page, criteria);
	}

	@DataProvider
	public void loadNewProject(Page<Project> page, Criteria criteria) {
		this.projectJdbcDao.loadNewProject(page, criteria);
	}

	/**
	 * 上传附件
	 * 
	 * @param file
	 * @param parameter
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unused")
	@FileResolver
	public String process2(UploadFile file, Map<String, Object> parameter) throws Exception {
		String name = (String) parameter.get("name");
		String basePath = Configure.getString("WENJIAN_FILE_UPLOAD_PATH");
		if (StringUtils.isEmpty(basePath)) {
			throw new IllegalArgumentException("必须指定档案文件上传的基本地址");
		}
		String returnValue = "";
		try {
			if (projectDao.check(name, (String) parameter.get("projectId"))) {
				String pathArr = "立项申请业务需求书";
				Path path = Paths.get(basePath, pathArr);
				if (!Files.isDirectory(path)) {
					path = Files.createDirectories(path);
				}
				path = path.resolve(UUID.randomUUID().toString());
				File destFile = Files.createFile(path).toFile();
				projectDao.saveProjectFile(name, path.toString());
				file.transferTo(destFile);
				returnValue = projectDao.getProjectFileId(name, path.toString());
			} else {
				returnValue = "error";
			}
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return returnValue;
	}

	/**
	 * 下载附件
	 * 
	 * @param parameter
	 * @return
	 * @throws IOException
	 */
	@FileProvider
	public DownloadFile download(Map<String, String> parameter) throws IOException {
		ProjectFile pfile = projectDao.getProjectFileById(parameter.get("id"));
		String fileName = pfile.getFileName();
		String path = pfile.getPath();
		InputStream stream = new FileInputStream(path);
		DownloadFile file = new DownloadFile(fileName, stream);
		return file;
	}

	/**
	 * 提交到基础运维科
	 * 
	 * @param project
	 * @param type
	 * @param username
	 */
	@Transactional
	@Expose
	public void commitJcywk(Project project, String xmshy) {
		try {
			// Project状态state 为5时表示审核中
			project.setState(5);
			projectDao.update(project);
			StartProcessInfo info = new StartProcessInfo();
			info.setPromoter(ContextHolder.getLoginUserName());
			info.setCompleteStartTask(true);
			info.setBusinessId(project.getId());
			String dm = null;
			if (project.getDeclareMeans().equals("1")) {
				dm = "集中式立项申请";
			} else if (project.getDeclareMeans().equals("2")) {
				dm = "非集中式立项申请";
			}
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("taskname", dm + "【" + project.getName() + "】 请立项审核员审核");
			map.put("agree", 1);
			map.put("xmshy", xmshy);
			info.setVariables(map);
			processClient.startProcessByName("立项申请", info);

		} catch (Exception e) {
			throw e;
			// TODO: handle exception
		}
	}

	/**
	 * 再次申请
	 * 
	 * @param taskId
	 * @param state
	 */
	@Expose
	public void ajaxRe(String taskId, Project project) {
		String dm = null;
		String qz = null;
		if (project.getHldqz() == 1) {
			qz = "已上传行领导签字";
		} else if (project.getHldqz() == 0) {
			qz = "请立项审核员审核";
		}
		if (project.getDeclareMeans().equals("1")) {
			dm = "集中式立项申请";
		} else if (project.getDeclareMeans().equals("2")) {
			dm = "非集中式立项申请";
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("taskname", dm + "【" + project.getName() + "】" + qz);

		taskClient.withdraw(Long.valueOf(taskId), map);
	}

	/**
	 * 撤销申请
	 * 
	 * @param taskId
	 * @param project
	 */
	@Transactional
	@Expose
	public void cheXiao(String taskId, Project project) {
		// PROJECT state设置为20,表示撤销流程
		project.setState(20);
		projectDao.update(project);
		taskClient.start(Long.valueOf(taskId));
		taskClient.forward(Long.valueOf(taskId), "结束4");
	}

	/**
	 * 根据部门名称获取部门Id
	 * 
	 * @param name
	 * @return
	 */
	@DataProvider
	public List<Map<String, Object>> loadDepts(String name) {

		return projectDao.loadDepts(name);
	}

	/**
	 * 判断目前时间是否是集中申报时间段
	 * 
	 * @return
	 */
	@Expose
	public boolean getDeclareTime() {
		return projectDao.getDeclareTime();
	}

	@DataProvider
	public List<Map<String, Object>> selectXmshy() {
		return projectDao.selectXmshy();
	}

	@Transactional
	@Expose
	public void zghldSh(String taskId, String opinionText, int i) {
		projectDao.zghldSh(taskId, opinionText, i);
	}

	@Transactional
	@DataResolver
	public void saveAndCommit(Project project, Map<String, Object> parameter) {
		List<Project> ls = new ArrayList<Project>();
		ls.add(project);
		this.saveProject(ls);
		this.commitJcywk(ls.get(0), (String) parameter.get("xmshy"));
	}

	@Expose
	public String checkDept(Record dept) throws Exception {

		Dept loginDept = (Dept) ContextHolder.getLoginUser().getDepts().get(0);
		Dept loginZZDept = (Dept) SecurityUtils.getZZByDept(loginDept);
		if (StringUtils.isNotBlank(dept.getString("deptLevel"))) {
			return "【" + dept.getString("name") + "】不属于部门,请重新选择!";
		} else if (dept.getString("id").startsWith(loginZZDept.getId()) == false) {
			return "【" + dept.getString("name") + "】不属于您所在的中支,请重新选择!";
		}
		return null;
	}

	/**
	 * 取消备案
	 * 
	 *
	 * @param project
	 */
	@Transactional
	@DataResolver
	public void qxba(Project project) {
		// PROJECT state设置为25,表示取消备案
		//project.setState(25);
		projectDao.update(project);
	}
}
